#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"
#include <math.h>
#include "testHelper.c"

#define NOISY_TEST 1

int checkSmithy(int testCardPos, struct gameState *testState) {
  int i, cardValue, functionError;
  struct gameState controlState;
  int bonus = 0;
  
  memcpy (&controlState, testState, sizeof(struct gameState));
  cardValue = testState->hand[testState->whoseTurn][testCardPos];
  //printf("***RELEVANT DATA FROM THE TEST***\n");
  //printf("Current Card Value in test = %d\n\n", cardValue);

  functionError = cardEffect (cardValue, 0, 0, 0, testState, testCardPos, &bonus);

  /* SIMULATE THE CARD EFFECT */
  for(i = 0; i < 3; i++){ //simulate three card draws
    drawCard(controlState.whoseTurn, &controlState);    
  }    
  discardCard(testCardPos, controlState.whoseTurn, &controlState, 0);
  
  assert(functionError == 0); //no error playing the card
  
  //test to see if both the states are the same
  if(memcmp(&controlState, testState, sizeof(struct gameState)) == 0){
    return 0;
  }
  else{
    gameStateDiff(&controlState, testState);
    return 1;
  }
}

int main () {

  int i, n, numPlayers, currentPlayer, seed, testCardPos, success, failure;

  int k[10] = {adventurer, council_room, feast, gardens, mine,
	       remodel, smithy, village, baron, great_hall};

  struct gameState G;
  
  printf ("***TESTING SMITHY***\n");

  success = 0;
  failure = 0;
  PutSeed(floor(Random() * MODULUS));

  for (n = 0; n < 2000; n++) {
    /* Fill the Game State with garbage */
    for (i = 0; i < sizeof(struct gameState); i++) {
      ((char*)&G)[i] = floor(Random() * 256);
    }
    //initialize new game
    numPlayers = floor(Random() * PLAYER_RANGE) + 2;
    seed = floor(Random() * 1000);
    initializeGame(numPlayers, k, seed, &G);
    
    for (i = 0; i < numPlayers; i++){
      G.deckCount[i] = floor(Random() * MAX_DECK) + 5; //enough cards to draw from
      G.discardCount[i] = floor(Random() * MAX_DECK);
      G.handCount[i] = floor(Random() * MAX_HAND);
    }
    currentPlayer = floor(Random() * numPlayers); //define a current random player
    G.whoseTurn = currentPlayer; //set the game's current player to selected player
    testCardPos = floor(Random() * G.handCount[currentPlayer]); //define a random card in the current player's hand to test
    G.hand[currentPlayer][testCardPos] = smithy; //set that card to a smithy
    if(checkSmithy(testCardPos, &G) == 0){
      success++;
    }
    else{
      failure++;
    }
  }

  printf ("\n***TESTS COMPLETE***\n***SUMMARY\n***Successful Tests: %d\n***Failed Tests: %d\n\n", success, failure); 

  return 0;
}
